package subterfuge;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;

import emergence.game.gfx.ColoredSprite;
import emergence.game.level.tiles.Tile;

public class RightSidebar extends JPanel {

    private static final long serialVersionUID = 1L;

    private Tile currentTile;
    private List<Tile> tiles;

    private JPanel currentTilePanel;
    private JLabel activeTileLabel;

    private JPanel buttonPanel;
    private JButton leftButton;
    private JButton rightButton;

    private JPanel displayPanel;

    private JPanel bigWrapper;

    private int[] colors = new int[216];

    public RightSidebar() {
        initColors();
        buildGui();
    }

    private void initColors() {
        int index = 0;
        for (int r = 0; r < 6; r++) {
            for (int g = 0; g < 6; g++) {
                for (int b = 0; b < 6; b++) {
                    int rr = (r * 255 / 5);
                    int gg = (g * 255 / 5);
                    int bb = (b * 255 / 5);

                    colors[index] = rr << 16 | gg << 8 | bb;
                    index++;
                }
            }
        }
    }

    private void buildGui() {
        this.setLayout(new BorderLayout());
        GridBagConstraints c;

        // Configure Current Tile Panel
        currentTilePanel = new JPanel();
        activeTileLabel = new JLabel("No Tile Selected", null, JLabel.CENTER);
        activeTileLabel.setVerticalTextPosition(JLabel.BOTTOM);
        activeTileLabel.setHorizontalTextPosition(JLabel.CENTER);
        Border activeTileLabelBorder = BorderFactory.createCompoundBorder(BorderFactory.createLoweredBevelBorder(), BorderFactory.createEmptyBorder(5, 5, 5, 5));
        activeTileLabel.setBorder(activeTileLabelBorder);
        currentTilePanel.add(activeTileLabel);

        // Configure Button Panel
        buttonPanel = new JPanel();
        leftButton = new JButton("<");
        rightButton = new JButton(">");
        buttonPanel.setLayout(new GridBagLayout());
        buttonPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1.0;
        c.weighty = 0.0;
        c.fill = GridBagConstraints.BOTH;
        buttonPanel.add(leftButton, c);

        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 0;
        c.weightx = 1.0;
        c.weighty = 0.0;
        c.fill = GridBagConstraints.BOTH;
        buttonPanel.add(Box.createRigidArea(new Dimension(50, 1)), c);

        c = new GridBagConstraints();
        c.gridx = 2;
        c.gridy = 0;
        c.weightx = 1.0;
        c.weighty = 0.0;
        c.fill = GridBagConstraints.BOTH;
        buttonPanel.add(rightButton, c);

        // Configure the Tile Display / Selection Panel
        displayPanel = new JPanel();
        displayPanel.setLayout(new GridLayout(0, 3)); // Change to compute based on screen size at some point

        // Configure the overall panel
        bigWrapper = new JPanel(new GridBagLayout());

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1.0;
        c.weighty = 0.0;
        c.anchor = GridBagConstraints.PAGE_END;
        c.fill = GridBagConstraints.BOTH;
        bigWrapper.add(currentTilePanel, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 1;
        c.weightx = 1.0;
        c.weighty = 0.0;
        c.fill = GridBagConstraints.BOTH;
        bigWrapper.add(buttonPanel, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 2;
        c.weightx = 1.0;
        c.weighty = 0.0;
        c.anchor = GridBagConstraints.PAGE_START;
        c.fill = GridBagConstraints.BOTH;
        bigWrapper.add(displayPanel, c);

        this.add(bigWrapper, BorderLayout.PAGE_START);
    }

    public void loadTiles(List<Tile> tiles) {
        this.tiles = tiles;
        Tile firstTile = tiles.get(0);
        updateActiveTile(firstTile);

        displayPanel.removeAll();

        for (Tile tile : tiles) {
            TileButton button = new TileButton(tile, 2);
            JPanel wrapper = new JPanel();
            wrapper.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
            wrapper.setLayout(new BorderLayout());
            wrapper.add(button, BorderLayout.CENTER);
            displayPanel.add(wrapper);
        }
    }

    public Tile currentTile() {
        return currentTile;
    }

    private void updateActiveTile(Tile tile) {
        currentTile = tile;
        if (tile == null) {
            activeTileLabel.setText("No Tile Selected");
        }
        else {
            activeTileLabel.setText("Active Tile: " + tile.name());
            activeTileLabel.setIcon(tileIcon(tile, 3));
        }
    }

    private ImageIcon tileIcon(Tile tile, int scale) {
        ColoredSprite sprite = tile.staticSprite();
        BufferedImage bfImg = new BufferedImage(sprite.width() * scale, sprite.height() * scale, BufferedImage.TYPE_INT_RGB);
        int[] pixels = ((DataBufferInt) bfImg.getRaster().getDataBuffer()).getData();
        for (int i = 0; i < sprite.width() * scale; i++) {
            for (int j = 0; j < sprite.height() * scale; j++) {
                if (sprite.pixels()[i / scale][j / scale] < 255) {
                    pixels[i + (j * sprite.width() * scale)] = colors[sprite.pixels()[i / scale][j / scale]];
                }
                else {
                    pixels[i + (j * sprite.width() * scale)] = this.getBackground().hashCode();
                }
            }
        }
        return new ImageIcon(bfImg);
    }

    private class TileButton extends JButton implements ActionListener {

        private static final long serialVersionUID = 1L;

        private Tile tile;

        public TileButton(Tile tile, int scale) {
            super(tile.name(), tileIcon(tile, scale));
            this.setVerticalTextPosition(JButton.BOTTOM);
            this.setHorizontalTextPosition(JButton.CENTER);

            this.addActionListener(this);

            this.tile = tile;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            updateActiveTile(tile);
        }
    }

}
